package com.leyou.order.service.impl;

import com.leyou.auth.pojo.UserInfo;
import com.leyou.common.dto.AddressDTO;
import com.leyou.common.dto.CartDTO;
import com.leyou.common.dto.OrderDTO;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.IdWorker;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.pojo.Sku;
import com.leyou.order.client.AddressClient;
import com.leyou.order.client.GoodsClient;
import com.leyou.order.enums.OrderStatusEnum;
import com.leyou.order.enums.PayStateEnum;
import com.leyou.order.interceptors.UserInterceptor;
import com.leyou.order.mapper.OrderDetailMapper;
import com.leyou.order.mapper.OrderMapper;
import com.leyou.order.mapper.OrderStatusMapper;
import com.leyou.order.pojo.Order;
import com.leyou.order.pojo.OrderDetail;
import com.leyou.order.pojo.OrderStatus;
import com.leyou.order.service.OrderService;
import com.leyou.order.utils.WxPayHelper;
import com.sun.org.apache.regexp.internal.RE;
import jdk.nashorn.internal.ir.IfNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private OrderStatusMapper orderStatusMapper;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private GoodsClient goodsClient;
    @Autowired
    private WxPayHelper wxPayHelper;


    @Override
    @Transactional
    public Long createOrder(OrderDTO orderDTO) {
        // 1. 新增订单表
        // 1.1 生成orderID, 其他order基本字段
        Order order = new Order();
        long orderId = idWorker.nextId();
        order.setOrderId(orderId);
        order.setPaymentType(1);
        order.setCreateTime(new Date());
        // 1.2 登录用户信息
        UserInfo user = UserInterceptor.getUser();
        order.setUserId(user.getId());
        order.setBuyerNick(user.getUsername());
        order.setBuyerRate(false);
        order.setBuyerMessage("");
        // 1.3 收货人信息
        AddressDTO address = AddressClient.findById(orderDTO.getAddressId());
        order.setReceiver(address.getName());
        order.setReceiverMobile(address.getPhone());
        order.setReceiverState(address.getState());
        order.setReceiverCity(address.getCity());
        order.setReceiverDistrict(address.getDistrict());
        order.setReceiverAddress(address.getAddress());
        order.setReceiverZip(address.getZipCode());
        // 1.4 订单金额: 查询商品价格,运算得到
        // 查询商品价格
        Map<Long, Integer> cartMap = orderDTO.getCarts().stream().collect(Collectors.toMap(CartDTO::getSkuId, CartDTO::getNum));
        ArrayList<Long> skuIds = new ArrayList<>(cartMap.keySet());
        List<Sku> skus = goodsClient.querySkuBySkuIds(skuIds);
        long totlaPay = 0L;
        // 订单详情集合
        List<OrderDetail> orderDetails = new ArrayList<>();
        for (Sku sku : skus) {
            Integer num = cartMap.get(sku.getId());
            totlaPay += sku.getPrice() * num;
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderId);
            orderDetail.setSkuId(sku.getId());
            orderDetail.setNum(num);
            orderDetail.setTitle(sku.getTitle());
            orderDetail.setPrice(sku.getPrice());
            orderDetail.setOwnSpec(sku.getOwnSpec());
            orderDetail.setImage(StringUtils.substringBefore(sku.getImages(), ","));
            orderDetails.add(orderDetail);
        }
        order.setTotalPay(totlaPay);
        // 实付金额 = 总金额 + 邮费 - 优惠
        long actualPay = totlaPay - order.getPostFee() - 0L;
        order.setActualPay(actualPay);
        // 写入数据库
        int count = orderMapper.insertSelective(order);
        if (count != 1) {
            throw new LyException(ExceptionEnum.CREATE_ORDER_ERROR);
        }
        // 2. 新增订单详情表
        // 2.1 根据skuId查询商品信息
        // 2.2 封装为orderDetail
        // 2.3 新增
        count = orderDetailMapper.insertList(orderDetails);
        if (count != orderDetails.size()) {
            throw new LyException(ExceptionEnum.CREATE_ORDER_DETAIL_ERROR);
        }
        // 3. 新增订单状态表
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orderId);
        orderStatus.setStatus(OrderStatusEnum.INIT.getStatus());
        orderStatus.setCreateTime(order.getCreateTime());
        count = orderStatusMapper.insertSelective(orderStatus);
        if (count != 1) {
            throw new LyException(ExceptionEnum.CREATE_ORDER_STATUS_ERROR);
        }

        // 4. 减库存
        List<CartDTO> cartDTOList = orderDTO.getCarts();
        goodsClient.decreaseStock(cartDTOList);

        return orderId;
    }

    @Override
    public Order queryOrderById(Long orderId) {

        // 查询订单表
        Order order = orderMapper.selectByPrimaryKey(orderId);
        if (order == null) {
            throw new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }
        // 查询订单详情表
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderId);
        List<OrderDetail> detailList = orderDetailMapper.select(orderDetail);
        if (CollectionUtils.isEmpty(detailList)) {
            throw new LyException(ExceptionEnum.ORDER_DETAIL_NOT_FOUND);
        }
        order.setOrderDetails(detailList);
        // 查询订单状态表
        OrderStatus orderStatus = orderStatusMapper.selectByPrimaryKey(orderId);
        if (orderStatus == null) {
            throw new LyException(ExceptionEnum.ORDER_STATUS_NOT_FOUND);
        }
        order.setOrderStatus(orderStatus);

        return order;
    }

    @Override
    public String generatePayUrl(Long orderId) {
        Order order = queryOrderById(orderId);
        if (order == null) {
            throw new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }

        OrderStatus orderStatus = order.getOrderStatus();
        if (orderStatus.getStatus() != OrderStatusEnum.INIT.getStatus()) {
            throw new LyException(ExceptionEnum.ORDER_STATUS_INVALID);
        }

        Long totalPay = /*order.getActualPay()*/ 1L;

        String desc = order.getOrderDetails().get(0).getTitle();

        String url = wxPayHelper.createOrder(orderId, totalPay, desc);

        return url;
    }

    @Override
    public void handleNotify(Map<String, String> msg) {
        // 1 数据校验
        wxPayHelper.isSuccess(msg);
        // 2 校验签名
        wxPayHelper.isValidSign(msg);

        String stringTotalFee = msg.get("total_fee");
        String stringOutTradeNo = msg.get("out_trade_no");
        if (StringUtils.isEmpty(stringTotalFee) || StringUtils.isEmpty(stringOutTradeNo)) {
            throw new LyException(ExceptionEnum.INVALID_ORDER_PARAM);
        }

        // 3.1 获取结果中的金额
        Long totalFee = Long.valueOf(stringTotalFee);

        // 3.2 获取订单金额
        Long orderId = Long.valueOf(stringOutTradeNo);
        Order order = orderMapper.selectByPrimaryKey(orderId);
        Long actualPay = /*order.getActualPay()*/ 1L;
        if (actualPay != totalFee) {
            // 金额不符
            throw new LyException(ExceptionEnum.INVALID_ORDER_PARAM);
        }

        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orderId);
        orderStatus.setStatus(OrderStatusEnum.PAY_UP.getStatus());
        orderStatus.setPaymentTime(new Date());
        int count = orderStatusMapper.updateByPrimaryKeySelective(orderStatus);
        if (count != 1) {
            throw new LyException(ExceptionEnum.UPDATE_ORDER_STATUS_ERROR);
        }

        log.info("[订单回调],订单支付成功! 订单编号: {}", orderId);

    }

    @Override
    public Integer queryPayStateByOrderId(Long orderId) {
        // 查询订单状态
        OrderStatus orderStatus = orderStatusMapper.selectByPrimaryKey(orderId);
        if (orderStatus == null) {
            throw new LyException(ExceptionEnum.ORDER_STATUS_NOT_FOUND);
        }

        // 判断是否支付
        if (orderStatus.getStatus() != OrderStatusEnum.INIT.getStatus()) {
            // 如果已支付,真的是已支付
            return PayStateEnum.SUCCESS.getValue();
        }

        // 如果未支付,但其实不一定是未支付,必须去微信查询支付状态
        return wxPayHelper.queryPayState(orderId).getValue();

    }
}
